﻿using System;
using System.Data;
using Microsoft.SqlServer.Server;
using System.Data.SqlTypes;
using System.IO;
using System.Text;


//use clr serialization to serialize the intermediate result
//optimizer property
//optimizer property
//optimizer property
//maximum size in bytes of persisted value
[Serializable]
[SqlUserDefinedAggregate(Format.UserDefined, IsInvariantToNulls = true, IsInvariantToDuplicates = false, IsInvariantToOrder = true, MaxByteSize = -1)]
public class LastAgg : IBinarySerialize
{
    private StringBuilder recs_buffer;

    // Initialize the internal data structures
    public void Init()
    {
        this.recs_buffer = new StringBuilder();
    }

    // Accumulate the next value, not if the value is null
    public void Accumulate(SqlString value)
    {

        if (value.IsNull)
        {
            return;
        }

        this.recs_buffer.Append(value.Value).Append(',');
    }

    // Merge the partially computed aggregate with this aggregate.
    public void Merge(LastAgg other)
    {
        this.recs_buffer.Append(other.recs_buffer);
    }

    // Called at the end of aggregation, to return the results of the aggregation.
    public SqlString Terminate()
    {
        string output = string.Empty;
        Int64 i = 0;
        //delete the trailing comma, if any
        if (this.recs_buffer != null && this.recs_buffer.Length > 0)
        {
            i = this.recs_buffer.ToString().Split(',').GetUpperBound(0);
            output = this.recs_buffer.ToString().Split(',')[i - 1];
        }
        else
            output = null;

        return new SqlString(output);
    }

    public void Read(BinaryReader r)
    {
        recs_buffer = new StringBuilder(r.ReadString());
    }

    public void Write(BinaryWriter w)
    {
        w.Write(this.recs_buffer.ToString());
    }
}
